//
//  BC_ZooRequest.m
//  CocOth
//
//  Created by BrunoCausse on 22/12/10.
//  Copyright 2010-2013 poulailler cie. All rights reserved.
//

#import "BC_ZooRequest.h"
#import "BC_Const.h"

//methodes privées
@interface BC_ZooRequest(PrivateAPI)
	
- (NSUInteger)hashing;

@end



@implementation BC_ZooRequest

@synthesize  splitpoint;

@synthesize	 parent, position;
@synthesize  move;
@synthesize	 depth, hash;
@synthesize  state;

@synthesize listMoves;
@synthesize score, time;

@dynamic cut;

-(NSUInteger)cut
{
	return cut;
}

- (void)setCut:(NSUInteger)selectivity
{
	cut = selectivity;
	hash = [self hashing];
}

@dynamic alpha, beta;

-(NSInteger)alpha
{
	return alpha;
}

- (void)setAlpha:(NSInteger)low
{
	alpha = low;
	hash = [self hashing];
}

-(NSInteger)beta
{
	return beta;
}

- (void)setBeta:(NSInteger)high
{
	beta = high;
	hash = [self hashing];
}


- (id)initWithPosition:(NSString *)pos
{
	
	return [self initWithPosition:pos 
							  cut:100];
}

- (id)initWithPosition:(NSString *)pos 
				  cut:(NSUInteger)selectivity
{
	return [self initWithPosition:pos 
							alpha:-64 
							 beta: 64 
							  cut:selectivity];
	
}


- (id)initWithPosition:(NSString *)pos 
				 alpha:(NSInteger)low 
				  beta:(NSInteger)high
{
	return [self initWithPosition:pos 
							alpha:low 
							 beta:high 
							  cut:100];
}


- (id)initWithPosition:(NSString *)pos 
				 alpha:(NSInteger)low 
				  beta:(NSInteger)high 
				   cut:(NSUInteger)selectivity
{
	
	
	return [self initWithPosition:pos 
							alpha:low 
							 beta:high
							depth:-1
							  cut:selectivity];
	
}

- (id)initWithPosition:(NSString *)pos 
				 alpha:(NSInteger)low 
				  beta:(NSInteger)high
				 depth:(NSInteger)aDepth
				   cut:(NSUInteger)selectivity
{
	return [self initWithPosition:pos 
							alpha:low 
							 beta:high 
							  cut:selectivity
							depth:aDepth
						   parent:pos
							 move:nil];
}

- (id)initWithPosition:(NSString *)pos 
				 alpha:(NSInteger)low 
				  beta:(NSInteger)high 
				   cut:(NSUInteger)selectivity
				 depth:(NSInteger)aDepth
				parent:(NSString *)posParent
				  move:(NSString *)aMove
{
		
	return [self initWithPosition:pos 
							alpha:low 
							 beta:high 
							  cut:selectivity
							depth:aDepth
						 priority:0
						   parent:posParent
							 move:aMove
					   splitpoint:nil];
	
}

- (id)initWithPosition:(NSString *)pos 
				 alpha:(NSInteger)low 
				  beta:(NSInteger)high 
				   cut:(NSUInteger)selectivity
				 depth:(NSInteger)aDepth
			  priority:(NSUInteger)aPriority
				parent:(NSString *)posParent
				  move:(NSString *)aMove
			splitpoint:(BC_SplitPoint *)sp

{
	self = [super init];
	if (self) {
				
		splitpoint	= sp; //simple assignation
		state		= WORKISWAITING;
		
		parent		= [posParent retain];
		move		= [aMove retain];
		
		position	= [pos retain];
		alpha		= low;
		beta		= high;
		cut			= selectivity;
		priority	= aPriority;
		depth		= 0;
		
		if(aDepth < 0) {
			for(int i=0; i<65; i++)
				if([position characterAtIndex:i] == '-')
					depth++;
		} else {
			depth = aDepth;
		}

		
		hash = [self hashing];
		
		score		= UNDEFSCORE;
		time		= UNDEFTIME;
		listMoves	= nil; //@"";
		
		myCondition = [[NSCondition alloc] init];
		
	}
	
	return self;
	
}



- (void)dealloc
{
	[myCondition release];
	
	[listMoves release];
	[position release];
	
	[move release];
	[parent release];
	
	[super dealloc];
}


- (NSUInteger)hashing
{
	NSMutableString *forHash = [NSMutableString stringWithCapacity:100];
	
	[forHash appendString:position];
	[forHash appendFormat:@"%ld%ld", alpha, beta];
	[forHash appendFormat:@"%ld", depth];
	[forHash appendFormat:@"%ld", cut];
	
	return [forHash hash] & 0x7fffffffffffffffull;
	
}

- (NSString *)request
{
	NSMutableString *req = [NSMutableString stringWithCapacity:200]; //autorelease
	
	[req appendFormat:@"&pos=%@", position];
	[req appendFormat:@"&window=%ld,%ld", alpha, beta];
	[req appendFormat:@"&depth=%ld", depth];
	[req appendFormat:@"&cut=%ld", cut];
	[req appendFormat:@"&priority=%ld", priority];
	[req appendFormat:@"&hash=%lx", hash];
	
	return req;
}


- (void)wait
{
	[myCondition lock];
	while(state == SEARCHING) {
		[myCondition wait];
	}
	[myCondition unlock];
}


- (void)signal:(request_state)aState
{
	[myCondition lock];
	state = aState;
	[myCondition signal];
	[myCondition unlock];
}

- (void)should_stop
{
	[self signal:STOP];
}
	


	


@end
